package cn.cytong.util;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * Created with IntelliJ IDEA.
 * User: TangGaowei
 * Date: 12-9-28
 * Time: 下午10:10
 * 处理日期变量
 */
public class DateTool {
    private final static String DEFAULT_PATTERN = "yyyy-MM-dd HH:mm:ss";

    public final static int AMOUNT_OF_SECOND = 1000;
    public final static int AMOUNT_OF_MINUTE = 1000 * 60;
    public final static int AMOUNT_OF_HOUR = 1000 * 60 * 60;
    public final static int AMOUNT_OF_DATE = 1000 * 60 * 60 * 24;

    /**
     * 计算开始时间与结束时间之间相差数量
     *
     * @param beginTime
     * @param endTime
     * @param field（天、小时、分钟、秒）
     * @return
     */
    public static Long margin(Date beginTime, Date endTime, int field) {
        Date bt = beginTime;
        Date et = endTime;

        // 格式化时间
        switch (field) {
            case Calendar.DATE:
                bt = clearTime(bt, "yyyy-MM-dd 00:00:00");
                et = clearTime(et, "yyyy-MM-dd 00:00:00");
                break;
            case Calendar.HOUR:
                bt = clearTime(bt, "yyyy-MM-dd HH:00:00");
                et = clearTime(et, "yyyy-MM-dd HH:00:00");
                break;
            case Calendar.MINUTE:
                bt = clearTime(bt, "yyyy-MM-dd HH:mm:00");
                et = clearTime(et, "yyyy-MM-dd HH:mm:00");
                break;
            case Calendar.SECOND:
                bt = clearTime(bt, "yyyy-MM-dd HH:mm:ss");
                et = clearTime(et, "yyyy-MM-dd HH:mm:ss");
                break;
        }

        // 相减
        long margin = et.getTime() - bt.getTime();

        // 计算
        switch (field) {
            case Calendar.DATE:
                margin = margin / AMOUNT_OF_DATE;
                break;
            case Calendar.HOUR:
                margin = margin / AMOUNT_OF_HOUR;
                break;
            case Calendar.MINUTE:
                margin = margin / AMOUNT_OF_MINUTE;
                break;
            case Calendar.SECOND:
                margin = margin / AMOUNT_OF_SECOND;
                break;
        }

        return margin;
    }

    // 处理天
    public static Long marginDate(Date beginTime, Date endTime) {
        return margin(beginTime, endTime, Calendar.DATE);
    }

    /**
     * 是否为 2013-01 格式的字符串
     *
     * @param month
     * @return
     */
    public static boolean isMonthString(String month) {
        return RegexTool.check(month, "\\d{4}-\\d{2}");
    }

    /**
     * 是否为 2013-01-01 格式的字符串
     *
     * @param date
     * @return
     */
    public static boolean isDateString(String date) {
        return RegexTool.check(date, "\\d{4}-\\d{2}-\\d{2}");
    }

    /**
     * 是否为 03:00 格式的字符串
     *
     * @param date
     * @return
     */
    public static boolean isHourMinuteString(String date) {
        return RegexTool.check(date, "\\d{2}:\\d{2}");
    }

    /**
     * 是否为 03:00:00 格式的字符串
     *
     * @param date
     * @return
     */
    public static boolean isTimeString(String date) {
        return RegexTool.check(date, "\\d{2}:\\d{2}:\\d{2}");
    }


    /**
     * 从年月字符串里提取年字符串
     *
     * @param date
     * @return
     */
    public static String yearOfMonthString(String date) {
        return RegexTool.value(date, RegexTool.getRegexString(null, "-\\d{2}"));
    }

    /**
     * 从年月字符串里提取月字符串
     *
     * @param date
     * @return
     */
    public static String monthOfMonthString(String date) {
        return RegexTool.value(date, RegexTool.getRegexString("\\d{4}-", null));
    }

    /**
     * 从年月日字符串里提取年字符串
     *
     * @param date
     * @return
     */
    public static String yearOfDateString(String date) {
        return RegexTool.value(date, RegexTool.getRegexString(null, "-\\d{2}-\\d{2}"));
    }

    /**
     * 从年月日字符串里提取月字符串
     *
     * @param date
     * @return
     */
    public static String monthOfDateString(String date) {
        return RegexTool.value(date, RegexTool.getRegexString("\\d{4}-", "-\\d{2}"));
    }

    /**
     * 从年月日字符串里提取日字符串
     *
     * @param date
     * @return
     */
    public static String dayOfDateString(String date) {
        return RegexTool.value(date, RegexTool.getRegexString("\\d{4}-\\d{2}-", null));
    }

    /**
     * 定位到当月第一天
     *
     * @param t
     * @return
     */
    public static Date firstDate(Date t) {
        String s = toString(t, "yyyy-MM-01 00:00:00");
        return valueOf(s);
    }

    /**
     * 定位到当月的最后一天
     *
     * @param t
     * @return
     */
    public static Date lastDate(Date t) {
        int amount = getDateOfMonth(t);
        String part = StringTool.toString(amount, 2);
        String s = toString(t, "yyyy-MM-" + part + " 00:00:00");
        return valueOf(s);
    }

    /**
     * 时分秒归零
     *
     * @param t
     * @return
     */
    public static Date clearTime(Date t) {
        return clearTime(t, "yyyy-MM-dd 00:00:00");
    }

    public static Date clearTime(Date t, String pattern) {
        String s = toString(t, pattern);
        return valueOf(s);
    }

    /**
     * 月份的天数
     *
     * @param t
     * @return
     */
    public static int getDateOfMonth(Date t) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(t);
        return cal.getActualMaximum(Calendar.DATE);
    }

    /**
     * 取中间时间
     *
     * @param beginTime
     * @param endTime
     * @return
     */
    public static Date middle(Date beginTime, Date endTime) {

        Long num = endTime.getTime() - beginTime.getTime();
        num = num / 1000;
        num = num / 2;

        return DateTool.add(beginTime, Calendar.SECOND, num.intValue());
    }

    /**
     * 获取星期
     *
     * @param t
     * @return
     */
    public static int getWeek(Date t) {
        Calendar c = Calendar.getInstance();
        c.setTime(t);
        return c.get(Calendar.DAY_OF_WEEK);
    }

    public static String getWeekText(Date t) {
        String result = "";
        int week = getWeek(t);

        switch (week) {
            case 1:
                result = "日";
                break;
            case 2:
                result = "一";
                break;
            case 3:
                result = "二";
                break;
            case 4:
                result = "三";
                break;
            case 5:
                result = "四";
                break;
            case 6:
                result = "五";
                break;
            case 7:
                result = "六";
                break;
        }

        return result;
    }

    /**
     * 获取 日、月、年、星期等等对应的数字
     *
     * @param t
     * @param field
     * @return
     */
    public static int getNumberOfDate(Date t, int field) {
        Calendar c = Calendar.getInstance();
        c.setTime(t);
        return c.get(field);
    }

    /**
     * 时间加减操作（amount<0为减）
     *
     * @param t
     * @param field
     * @param amount
     * @return
     */
    public static Date add(Date t, int field, int amount) {
        Date result = t;

        Calendar c = Calendar.getInstance();
        c.setTime(t);   //设置当前日期
        c.add(field, amount); //日期加1
        result = c.getTime(); //结果

        return result;
    }

    public static long now() {
        return (new Date()).getTime();
    }

    /**
     * 把日期转换成字符串
     *
     * @param date
     * @param pattern
     * @return
     */
    public static String toString(Date date, String pattern) {
        if (date != null) {
            DateFormat format;
            if (pattern == null || pattern.equals("")) {
                format = new SimpleDateFormat(DEFAULT_PATTERN);
            } else {
                format = new SimpleDateFormat(pattern);
            }

            return format.format(date);

        }
        return "";
    }

    public static String toString(java.sql.Timestamp t) {
        Date date = new Date(t.getTime());

        return toString(date);
    }

    public static String toString(java.sql.Timestamp t, String pattern) {
        Date date = new Date(t.getTime());

        return toString(date, pattern);
    }

    public static String toString(Date date) {
        return toString(date, DEFAULT_PATTERN);
    }

    /**
     * 把字符串转换成日期类型
     *
     * @param date
     * @param pattern
     * @return
     */
    public static Date valueOf(String date, String pattern) {
        if (date != null) {
            DateFormat format;
            if (pattern == null || pattern.equals("")) {
                format = new SimpleDateFormat(DEFAULT_PATTERN);
            } else {
                format = new SimpleDateFormat(pattern);
            }

            try {
                return format.parse(date);
            } catch (ParseException e) {
                e.printStackTrace();
            }

        }
        return null;
    }


    public static Date valueOf(String date) {
        if (StringTool.isEmpty(date)) {
            return null;
        }

        // 例：2013-01-07 10:12
        if (RegexTool.check(date, "[0-9]{4}-[0-9]{1,2}-[0-9]{1,2} [0-9]{1,2}:[0-9]{1,2}")) {
            date += ":00";
        }

        // 例：2013-01-07 10
        if (RegexTool.check(date, "[0-9]{4}-[0-9]{1,2}-[0-9]{1,2} [0-9]{1,2}")) {
            date += ":00:00";
        }

        // 例：2013-01-07
        if (RegexTool.check(date, "[0-9]{4}-[0-9]{1,2}-[0-9]{1,2}")) {
            date += " 00:00:00";
        }

        return valueOf(date, DEFAULT_PATTERN);
    }

    /**
     * 剩余（*天*小时*分*秒）
     */
    public static Map<String, Integer> balance(Date bt, Date et) {
        Map<String, Integer> ret = new HashMap<String, Integer>();
        if (bt != null && et != null && et.getTime() > bt.getTime()) {
            int count = 0;
            Calendar cbt = Calendar.getInstance();
            Calendar cet = Calendar.getInstance();
            cbt.setTime(bt);
            cet.setTime(et);

            // 日
            long time = et.getTime() - bt.getTime();
            long data = 1000 * 60 * 60 * 24;
            count = Long.valueOf(time / data).intValue();
            if(data * count > time){
                count--;
            }
            bt = add(bt, Calendar.DATE, count);
            ret.put("DATE", count);

            // 小时
            time = et.getTime() - bt.getTime();
            data = 1000 * 60 * 60;
            count = Long.valueOf(time / data).intValue();
            if(data * count > time){
                count--;
            }
            bt = add(bt, Calendar.HOUR, count);
            ret.put("HOUR", count);

            // 分
            time = et.getTime() - bt.getTime();
            data = 1000 * 60;
            count = Long.valueOf(time / data).intValue();
            if(data * count > time){
                count--;
            }
            bt = add(bt, Calendar.MINUTE, count);
            ret.put("MINUTE", count);

            // 秒
            count = Long.valueOf((et.getTime() - bt.getTime()) / 1000l).intValue();
            ret.put("SECOND", count);

            /*
            System.out.println(bt.getTime());
            System.out.println(et.getTime());

            Calendar cbt = Calendar.getInstance();
            Calendar cet = Calendar.getInstance();
            cbt.setTime(bt);
            cet.setTime(et);

            // 基本数据
            int beginYear = cbt.get(Calendar.YEAR);
            int endYear = cet.get(Calendar.YEAR);
            int beginMonth = cbt.get(Calendar.MONTH);
            int endMonth = cet.get(Calendar.MONTH);
            int beginDay = cbt.get(Calendar.DATE);
            int endDay = cet.get(Calendar.DATE);
            int beginHour = cbt.get(Calendar.HOUR);
            int endHour = cet.get(Calendar.HOUR);
            int beginMinute = cbt.get(Calendar.MINUTE);
            int endMinute = cet.get(Calendar.MINUTE);
            int beginSecond = cbt.get(Calendar.SECOND);
            int endSecond = cet.get(Calendar.SECOND);

            // 年
            int year = endYear - beginYear;
            Date temp = add(bt, Calendar.YEAR, year);
            if(temp.getTime() > et.getTime()){
                year -= 1;
            }
            if(endMonth < beginMonth){
                year -= 1;
                endMonth += 12;
            }
            ret.put("year", year);

            // 月
            ret.put("month", endMonth - beginMonth);

            // 日
            ret.put("day", endDay - beginDay);

            // 小时
            ret.put("hour", endHour - beginHour);

            // 分
            ret.put("minute", endMinute - beginMinute);

            // 秒
            ret.put("second", endSecond - beginSecond);
             */


        }

        return ret;
    }

    /**
     * 相差几天（多余的小时都不算，非四舍五入）
     *
     * @param bt
     * @param et
     * @return
     */
    public static int days(Date bt, Date et) {
        int ret = 0;
        if (bt != null && et != null && et.getTime() > bt.getTime()) {
            long time = et.getTime() - bt.getTime();
            long data = 1000 * 60 * 60 * 24;
            Long count = time / data;
            if(data * count > time){
                count--;
            }
            ret = count.intValue();
        }
        return ret;
    }

    /**
     * 相差的小时数
     * @param bt
     * @param et
     * @return
     */
    public static int hours(Date bt, Date et) {
        int ret = 0;
        if (bt != null && et != null && et.getTime() > bt.getTime()) {
            long time = et.getTime() - bt.getTime();
            long data = 1000 * 60 * 60;
            Long count = time / data;
            if(data * count > time){
                count--;
            }
            ret = count.intValue();
        }
        return ret;
    }

    /**
     * 相差的分钟数
     * @param bt
     * @param et
     * @return
     */
    public static int minutes(Date bt, Date et) {
        int ret = 0;
        if (bt != null && et != null && et.getTime() > bt.getTime()) {
            long time = et.getTime() - bt.getTime();
            long data = 1000 * 60;
            Long count = time / data;
            if(data * count > time){
                count--;
            }
            ret = count.intValue();
        }
        return ret;
    }

    /**
     * 相差的分钟数
     * @param bt
     * @param et
     * @return
     */
    public static int seconds(Date bt, Date et) {
        int ret = 0;
        if (bt != null && et != null && et.getTime() > bt.getTime()) {
            long time = et.getTime() - bt.getTime();
            long data = 1000;
            Long count = time / data;
            if(data * count > time){
                count--;
            }
            ret = count.intValue();
        }
        return ret;
    }
}
